LouProof = function () {
}

// Log, for logging errors.

LouProof.prototype.log = function( msg, lvl) {
    if( console !== null && LouProof.debuck <= lvl) {
        console.log( msg);
    }
}

// Dump, similar to php's print_r

LouProof.prototype.dump = function(arr, max_level, level) {

    if( !max_level) max_level = 1;
    var dumped_text = "";
    if (!level) level = 0;

    //The padding given at the beginning of the line.
    var level_padding = "";
    for (var j = 0; j < level + 1; j++) level_padding += "    ";

    if (typeof(arr) == 'object') { //Array/Hashes/Objects
        for (var item in arr) {
            var value = arr[item];

            if (typeof(value) == 'object') { //If it is an array,
                dumped_text += level_padding + "'" + item + "' ...\n";
                
                if( level < max_level) dumped_text += dump(value, 0, level + 1);
            } else {
                dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
            }
        }
    } else { //Stings/Chars/Numbers etc.
        dumped_text = "===>" + arr + "<===(" + typeof(arr) + ")";
    }
    return dumped_text;
}

LouProof.prototype.options_page = function() {
    page = new webfrontend.gui.ConfirmationWidget();
    
    var bgImg = new qx.ui.basic.Image("webfrontend/ui/bgr_detailinfo_br.png");
    page.dialogBackground._add(bgImg, {left: 0, top: 0});
    
    var la = new qx.ui.basic.Label("Shortcut Options");
        la.setFont("font_subheadline_sidewindow");
        la.setTextColor("text-gold");
        la.setTextAlign("left");
    page.dialogBackground._add(la, {left: 17, top: 5});
        
    var okButton = new qx.ui.form.Button("OK");
        okButton.setWidth(120);
        okButton.addListener("click", function(){page.disable();}, false);
    page.dialogBackground._add(okButton, {left: 440, top: 210});
    
    a.getDesktop().add(page, {left: 0, right: 0, top: 0, bottom: 0});
}

LouProof.prototype.upgrade_vis = function() {
    var cityid = a.buildingDetailView.cityId;
    var placeid = a.buildingDetailView.visBuilding.getId();
    var typeid = a.buildingDetailView.visBuilding.getType();
    
    this.upgrade( cityid, placeid, typeid, true);
}

LouProof.prototype.upgrade_bld = function( bld, isPaid) {
    var cityid = wfe.data.City.getInstance().getId();
    
    if( bld) {
        var placeid = bld.getId();
        var typeid = bld.getType();
    
        this.upgrade( cityid, placeid, typeid, isPaid);
    } else {
        if( debuck) this.log( 'Can\'t upgrade non-specified building: '+bld);
    }
}

LouProof.prototype.upgrade = function( cityid, placeid, typeid, isPaid) {
    
    // Making sure there's enough room in the build queue
    
    var maxq = webfrontend.data.Player.getInstance().getMaxBuildQueueSize();
    var qsize = this.building_queue_size();
    
    if( qsize >= maxq) {
        if( debuck) this.log( 'Can\'t upgrade building, queue is full!');
        return;
    }
    
    if( debuck) this.log( 'upgrading');
    if( debuck) this.log( 'Upgrading building (cityid, buildingid, type) '+
                             '('+cityid+', '+placeid+', '+typeid+')');
    
    webfrontend.net.CommandManager.getInstance().sendCommand(
        'UpgradeBuilding', {
        cityid: cityid,
        buildingid: placeid,
        buildingType: typeid,
        isPaid: isPaid
    }, this, this._onBuildDone, this.cntSetPlace);
    // upgrade( a.buildingDetailView.cityId, a.buildingDetailView.visBuilding.getId(), a.buildingDetailView.visBuilding.getType());
}

LouProof.prototype.buy_moonstone = function() {
    
    var moontowerid = this.get_moonstone_tower();
    
    if( !moontowerid) {
        if( debuck) this.log( "No level 10 moonglow tower found");
        return;
    }
    
    webfrontend.net.CommandManager.getInstance().sendCommand('CreateMoonStone', {
        cityid: wfe.data.City.getInstance().getId(),
        buildingid: moontowerid
    }, null, null);
}

LouProof.prototype.get_moonstone_tower = function() {
    var buildings = a.visMain.getBuildings();
    
    for (var i=0; i<buildings.length; i++) {
        if( (buildings[i].getType() == 36) && (buildings[i].getLevel() == 10) )
            return buildings[i].getId();
    }
    
    return false;
}

LouProof.prototype.building_queue_size = function() {
    // returns the number of buildings in the build queue

    city = webfrontend.data.City.getInstance();
    
    if( city.hasBuildQueue()) {
        return city.getBuildQueue().length;
    } else {
        return 0;
    }
}

LouProof.prototype.downgrade = function() {
    var cityid = a.buildingDetailView.cityId;
    var placeid = a.buildingDetailView.visBuilding.getId();
    var typeid = a.buildingDetailView.visBuilding.getType();
    
    webfrontend.net.CommandManager.getInstance().sendCommand(
        'DowngradeBuilding', {
        cityid: cityid,
        buildingid: placeid,
        buildingType: typeid,
        isPaid: true
    }, this, this._onBuildDone, this.cntSetPlace);
    // downgrade( a.buildingDetailView.cityId, a.buildingDetailView.visBuilding.getId(), a.buildingDetailView.visBuilding.getType());
}

LouProof.prototype.parse_chat = function( e) {
    var label = e.getData();

    label.setSelectable( true); // make the chat line selectable

    value = label.getValue();

    var re = new RegExp( ": .*"+p.$$user_name, 'i'); // Highlighting line on username
    if( re.test( value)) {
        value = value.replace( /^(.*?): (.*)$/, "$1: <span style='color: orange; background-color: black;'>$2</span>");
    }

    value = value.replace( /<\/span>\] says to \w+:/, "<\/span>]:");  // Removing "says to:" text
    value = value.replace( /https?:\/\/([-\w\.]+)+(:\d+)?(\/([\w/_\.]*(\?\S+)?)?)?/, '<a href="$&" target="_black" rel="nofollow" style="color:white;">$&</a>'); // Making URLs clickable

    label.setValue( value);
}

LouProof.prototype.chatSelectable = function( tabno) {
    // Makes the chat area selectable
    // Would be great if lines were selectable when they were added
    // instead of looping through it

    if(a.chat === null || a.chat.chatViewComposite === null) return;
    
    for( var cvc=0; cvc<a.chat.chatViewComposite.length; cvc++) {

        var lines = a.chat.chatViewComposite[ cvc].getChildren();

        for( var line=0; line<lines.length; line++) {

            lines[ line].setSelectable( true);
        }
    }
}

LouProof.prototype.from_hash = function( hashId) {
    return qx.core.ObjectRegistry.fromHashCode( hashId);
}

LouProof.prototype.qcount = function( bld) {
    // Returns the number of times a building is in the building queue
    
    city = wfe.data.City.getInstance();
    count = 0;
    
    if(! city["buildQueue"]) return 0; // If there's no queue, return 0
    
    for( var i=0; i<city.buildQueue.length; i++) {
        if( city.buildQueue[i].building == bld.getId()) {
            count++;
            if( debuck) this.log( 'Building found in queue: '+ bld.getId());
        }
    }
    
    return count;
}

// Simple play sound routine using the new HTML5 audio element

LouProof.prototype.play_sound = function( src) {
    var sound = new Audio( src);
    sound.play();
}

// Initialisation routine

LouProof.prototype.init = function() {

    wfe = webfrontend;

    p = wfe.data.Player.getInstance();
    c = wfe.data.Chat.getInstance();
    a = qx.core.Init.getApplication();

    // Chat selectable routine
    //setInterval( "louproof.chatSelectable();", 2000);

    // replacing standard error handling
    qx.event.GlobalError.setErrorHandler(function(ex) {
        louproof.log(ex);
      });

    debuck = false;
    
    this.populate_build_times();

    // Default options
    
    if( !localStorage["moonstone"]) localStorage["moonstone"] = "false";
    if( !localStorage["beep_on_name"]) localStorage["beep_on_name"] = "true";
    if( !localStorage["lowest_build_time"]) localStorage["lowest_build_time"] = "false";
    if( !localStorage["show_max_storage"]) localStorage["show_max_storage"] = "true";
    if( !localStorage["max_storage_separator"]) localStorage["max_storage_separator"] = "/";
    if( !localStorage["debug"]) localStorage["debug"] = "false";

    // Selecting alliance chat

    a.chat.tabView.setSelection( [a.chat.tabView.getChildren()[1]]);

    // Chat beeping
    webfrontend.data.Chat.getInstance().addListener( 'newMessage', function(e)
        {
            var re = new RegExp( p.$$user_name, 'i');
            var msg = e.getData();

            if ( (re.test( msg.m) || msg.c=="privatein") && (localStorage["beep_on_name"] == "true")) {
                //TODO: Access alert.ogg from within the plugin
                //this.play_sound( "chrome-extension://pmjkjnnfljmjjcpaenohknbhnpidlhml/alert.ogg");
                louproof.play_sound( "http://canvas.xieke.com/paddlewar_paddlebounce.ogg");
            }
        });

    // Chat parsing
    for( var cvc=0; cvc<a.chat.chatViewComposite.length; cvc++) {
        a.chat.chatViewComposite[ cvc].addListener( "addChildWidget", louproof.parse_chat, false);
    }
    
    // Keyboard shortcuts
    a.mainContainer.addListener( 'keypress', function(key) {
        
        if( !a.allowHotKey) { return; } // this is false if the chat input box is active
        
        var visbuilding = a.buildingDetailView.visBuilding; // can't do upgrade/downgrade without
                                                        // building being selected
        
        var identifier = key.getKeyIdentifier();
        var shift = key.isShiftPressed();
        var ctrl = key.isCtrlPressed();

        if( debuck) louproof.log( 'Key pressed.identifier = '+ identifier);
        
        if( identifier == 'U' && visbuilding) { // upgrade
            if( shift) { // full upgrade
                var level = a.buildingDetailView.visBuilding.getLevel();
                
                for( var i=level; i<10; i++) {
                    louproof.upgrade_vis();
                }
            } else { // single upgrade
                louproof.upgrade_vis();
            }
        }
        
        if( identifier == 'D' && visbuilding) { // downgrade
            if( shift) { // full downgrade
                level = a.buildingDetailView.visBuilding.getLevel();
                
                for( var i=level; i>0; i--) {
                    louproof.downgrade();
                }
            } else { // single downgrade
                louproof.downgrade();
            }
        }
        
        if( identifier == '[' || identifier == ',') { // previous city
            a.cityBar.prevButton.execute();
        }
        
        if( identifier == ']' || identifier == '.') { // next city
            a.cityBar.nextButton.execute();
        }
        
        // Lowest level building upgrades
        
        if( identifier == 'M') { // upgrade lowest level military building
            louproof.upgrade_bld( louproof.get_lowest_level_building( 'military'), !shift);
        }
        
        if( identifier == 'C') { // upgrade lowest level cottage
            louproof.upgrade_bld( louproof.get_lowest_level_building( 'cottage'), !shift);
        }

        if( identifier == 'B') { // upgrade lowest level barracks
            louproof.upgrade_bld( louproof.get_lowest_level_building( 'barracks'), !shift);
        }
        
        if( identifier == 'T') { // upgrade lowest level tower
            louproof.upgrade_bld( louproof.get_lowest_level_building( 'tower'), !shift);
        }
        
        if( identifier == 'A') { // Upgrade lowest level building
            louproof.upgrade_bld( louproof.get_lowest_level_building( 'all'), !shift);
        }
        
        if( identifier == 'L') { // upgrade lowest level common building
            louproof.upgrade_bld( louproof.get_lowest_level_building( 'common'), !shift);
        }
        
        if( identifier == 'R') { // show recruitment window
            qx.core.Init.getApplication().showRecruting();
        }
        
        //if( identifier == 'T') { // show trade (but not go outside city)
//            qx.core.Init.getApplication().showTrade();
        //}
        
        if( identifier == '+') { // Maximize chat window width
            for(var i=1; i<=3; i++) {
                a.chat.chatSize[ i].width = screen.width-500;
            }
            
            if( debuck) this.log( 'Maximizing chat window width');
            a.chat.setSizeMode( a.chat.sizeMode);
        }
        
        if( identifier == 'S') {
            // Buy moonstones
            
            if( (localStorage["moonstone"] == "false") && 
                ((a.buildingDetailView.visBuilding == null) ||
                (!a.buildingDetailView['buyMoonstoneButton'].getEnabled()))) {
                return;
            }
            
            if( shift) { // Buy 10 of em!
                for( var i=0; i<10; i++) {
                    louproof.buy_moonstone();
                }
            } else { // Buy just one of em
                louproof.buy_moonstone();
            }
        }
        
        if( identifier == 'O') {
            // Show options page
            louproof.show_options_window();
        }
        
        if( identifier == '-') { // Restore chat window width
            for(var i=1; i<=3; i++) {
                a.chat.chatSize[ i].width = 600;
            }
            
            if( debuck) this.log( 'Restoring chat window width');
            a.chat.setSizeMode( a.chat.sizeMode);
        }
        
        if( identifier == ';') {
            var re = /^([0-9]+)[:,-]([0-9]+)$/;
            var coords = prompt( "Enter co-ordinates");
            
            if( re.test( coords)) {
                var co_ar = re.exec( coords);
                
                var output = '[u][w='+ co_ar[1]*128 +';'+ co_ar[2]*80 +
                             ']'+ coords +'[/w][/u]';

                var curvalue = '';
                
                if( !(a.chat.chatLine.getValue() == null))
                    curvalue = a.chat.chatLine.getValue();
        
                if ( curvalue == 'nl') curvalue = '';
                a.chat.chatLine.setValue( curvalue + output);
                setTimeout( "a.chat.chatLine.focus()", 100); // Delay otherwise it adds the C to the end of the line
            }
        }
            
    }, null);
    
    if( p.$$user_name == "chainsawdaz")
    {
        //wfe.data.Chat.getInstance().addMsg( msg[louproof.rnd(8)]);
    }
    

    // Setting resource label values

    if( localStorage["show_max_storage"] == "true") {
        try {
            var rv = a.cityBar.resValueLabels;

            var rv_s = rv[1]._applyValue.toString();
            //var matches = rv_s.match( /^function \((\w+),(\w+)\){([^]*)}/m);
            var matches = rv_s.match( /^function \((\w+),\s*(\w+)\)\s*{([^]*)}/m)

            var arg1 = matches[1];
            var arg2 = matches[2]
            var body = matches[3];

            matches = rv_s.match( /this\.fireDataEvent\((\w+),/);

            var arg3 = matches[1];

            for( var i=1; i<=4; i++) {
                var new_body = "\n\
                \n\
                var max = webfrontend.data.City.getInstance().getResourceMaxStorage("+i+");\n\
                var second;\n\
                if( localStorage['show_empty_storage'] == 'true') {\n\
                    second = max-"+arg1+";\n\
                } else {\n\
                    second = max;\n\
                }\n\
                var new_value;\n\
                var "+arg3+"='changeContent';\n\
                \n\
                if( "+arg1+" > 999999) {\n\
                    "+arg1+" = (Math.floor( "+arg1+"/100000)/10) +''+ localStorage['max_storage_separator']\n\
                             + (Math.floor( second/100000)/10) +'m';\n\
                } else {\n\
                "+arg1+" = (Math.floor( "+arg1+"/1000)) +''+ localStorage['max_storage_separator']\n\
                         + (Math.floor( second/1000)) +'k';\n\
                }\n\n";

                new_body += body;

                rv[i]._applyValue = new Function( arg1, arg2, new_body);

                rv[i]._applyValue( rv[i].getValue(), 0);
        } } catch(e) { this.log( e); }
    }
}

LouProof.prototype.rnd = function( max) {
    return( Math.floor( Math.random()*max));
}

LouProof.prototype.is_common_btype = function( btype) {
    switch( btype) {
        case 1:
        case 2:
        case 3:
        case 4:
        case 6:
        case 7:
        case 8:
        case 10:
        case 11:
        case 13:
            return true;
            break;
    } 

    return false;
}

LouProof.prototype.is_resource = function( btype) {
    switch( btype) {
        case 27:
        case 28:
        case 29:
        case 30:
            return true;
            break;
    }

    return false;
}
    
LouProof.prototype.is_tower = function( btype) {
    switch( btype) {
        case 24:
        case 25:
        case 26:
        case 38:
        case 39:
        case 40:
        case 41:
        case 42:
        case 43:
        case 44:
        case 45:
        case 46:
            return true;
            break;
    }
    
    return false;
}

LouProof.prototype.is_barracks = function( btype) {
    return( btype == 14);
}

LouProof.prototype.is_cottage = function( btype) {
    return( btype == 4);
}


LouProof.prototype.is_military = function( btype) {
    switch( btype) {
        case 15:
        case 16:
        case 17:
        case 18:
        case 19:
        case 36:
        case 37:
            return true;
            break;
    }
    
    return false;
}

LouProof.prototype.getBldTypeName = function( bldType) {
    resmain = webfrontend.res.Main.getInstance();
    
    return resmain.buildings[bldType].dn;
}

// LouProof.prototypeoptions_window = webfrontend.gui.overlayWidget;

// * OPTIONS WINDOW

LouProof.prototype.options_window = function() { };
//LouProof.prototype.options_window.prototype.options = function() { };

LouProof.prototype.show_options_window = function() {

    var i =0;
    this.options_window = new webfrontend.gui.OverlayWidget();
    var options_canvas = new qx.ui.layout.Canvas();

    this.options_window.options = function() {
        this.moonstone = null;
        this.beep_on_name = null;
        this.saveclose = null;
        this.show_max_storage = null;
        this.max_storage_separator = null;
    }
    
    this.options_window.setTitle( this.options_window.tr( 'Keyboard Shortcut Options'));
    this.options_window.clientArea.setLayout( options_canvas);
    
    // Moonstone option
    
    this.options_window.options.moonstone = new qx.ui.form.CheckBox( "Buy moonstones without selecting tower");
    this.options_window.options.moonstone.setFont("font_subheadline_sidewindow");
    this.options_window.options.moonstone.setTextColor("text-black");
    
    if( localStorage["moonstone"] == "true")
        this.options_window.options.moonstone.setValue( true);
    
    // Beep on name option
    
    this.options_window.options.beep_on_name = new qx.ui.form.CheckBox( "Beep when user name appears in chat and on whisper");
    this.options_window.options.beep_on_name.setFont("font_subheadline_sidewindow");
    this.options_window.options.beep_on_name.setTextColor("text-black");
    
    if( localStorage["beep_on_name"] == "true")
        this.options_window.options.beep_on_name.setValue( true);
    
    // Upgrade sort by build time option
    
    this.options_window.options.lowest_build_time = new qx.ui.form.CheckBox( "Upgrade by lowest build time instead of lowest level");
    this.options_window.options.lowest_build_time.setFont("font_subheadline_sidewindow");
    this.options_window.options.lowest_build_time.setTextColor("text-black");
    
    if( localStorage["lowest_build_time"] == "true")
        this.options_window.options.lowest_build_time.setValue( true);

    // Show max storage on city resource bar

    this.options_window.options.show_max_storage = new qx.ui.form.CheckBox( "Show maximum storage on city resource bar (needs refresh)");
    this.options_window.options.show_max_storage.setFont("font_subheadline_sidewindow");
    this.options_window.options.show_max_storage.setTextColor("text-black");
    
    if( localStorage["show_max_storage"] == "true")
        this.options_window.options.show_max_storage.setValue( true);

    // Max storage separator
    
    this.options_window.options.max_storage_label = new qx.ui.basic.Label( "Max Storage Separator");
    this.options_window.options.max_storage_label.setFont( "font_subheadline_sidewindow");
    this.options_window.options.max_storage_label.setTextColor("text-black");
    
    this.options_window.options.max_storage_separator = new qx.ui.form.TextField( localStorage["max_storage_separator"]);
    this.options_window.options.max_storage_separator.setWidth( 20);
    this.options_window.options.max_storage_separator.setMaxLength( 1);
    this.options_window.options.max_storage_separator.setFont("font_subheadline_sidewindow");
    this.options_window.options.max_storage_separator.setTextColor("text-black");
    
    // Empty Storage
    //
     this.options_window.options.show_empty_storage = new qx.ui.form.CheckBox( "Show empty storage instead of max storage");
    this.options_window.options.show_empty_storage.setFont("font_subheadline_sidewindow");
    this.options_window.options.show_empty_storage.setTextColor("text-black");
    
    if( localStorage["show_empty_storage"] == "true")
        this.options_window.options.show_empty_storage.setValue( true);

    // Save & Close button
    
    this.options_window.saveclose = new qx.ui.form.Button( "Save & Close");
    
    this.options_window.saveclose.addListener( 'execute', function() {

                // TODO: louproof. needs to be replaced with this. or similar
                localStorage["moonstone"] = louproof.options_window.options.moonstone.getValue();
                localStorage["beep_on_name"] = louproof.options_window.options.beep_on_name.getValue();
                localStorage["lowest_build_time"] = louproof.options_window.options.lowest_build_time.getValue();
                localStorage["show_max_storage"] = louproof.options_window.options.show_max_storage.getValue();
                localStorage["max_storage_separator"] = louproof.options_window.options.max_storage_separator.getValue();
                localStorage["show_empty_storage"] = louproof.options_window.options.show_empty_storage.getValue();

                // Refresh the max storage res items

                var rs = a.cityBar.resValueLabels;
                for( var i=1; i<=4; i++) rs[i]._applyValue( rs[i].getValue(), 0);

                louproof.options_window.hide();
            }
        );
    
    // Adding the elements to the client area
            
    this.options_window.clientArea.add( this.options_window.options.moonstone,
            {left: 17, top: 20});
    this.options_window.clientArea.add( this.options_window.options.beep_on_name,
            {left: 17, top: 50});
    this.options_window.clientArea.add( this.options_window.options.lowest_build_time,
            {left: 17, top: 80});
    this.options_window.clientArea.add( this.options_window.options.show_max_storage,
            {left: 17, top: 110});
    this.options_window.clientArea.add( this.options_window.options.max_storage_label,
            {left: 17, top: 140});
    this.options_window.clientArea.add( this.options_window.options.max_storage_separator,
            {left: 220, top: 140});
    this.options_window.clientArea.add( this.options_window.options.show_empty_storage,
            {left: 17, top: 170});
    this.options_window.clientArea.add( this.options_window.saveclose,
            {left: 17, bottom: 10});
    
    a.switchOverlay( this.options_window);
}

// ---------------------

LouProof.prototype.build_time = null;

LouProof.prototype.populate_build_times = function() {

    this.build_time = new Array();

    this.build_time[12] = new Array(); //Town Hall
    this.build_time[12][1] = 0;
    this.build_time[12][2] = 25;
    this.build_time[12][3] = 40;
    this.build_time[12][4] = 100;
    this.build_time[12][5] = 1800;
    this.build_time[12][6] = 9000;
    this.build_time[12][7] = 18240;
    this.build_time[12][8] = 60000;
    this.build_time[12][9] = 93600;
    this.build_time[12][10] = 134400;

    this.build_time[1] = new Array(); //Woodcutter's Hut
    this.build_time[1][1] = 15;
    this.build_time[1][2] = 54;
    this.build_time[1][3] = 360;
    this.build_time[1][4] = 2700;
    this.build_time[1][5] = 6075;
    this.build_time[1][6] = 12150;
    this.build_time[1][7] = 22500;
    this.build_time[1][8] = 35820;
    this.build_time[1][9] = 53880;
    this.build_time[1][10] = 81720;

    this.build_time[4] = new Array(); //Cottage
    this.build_time[4][1] = 15;
    this.build_time[4][2] = 54;
    this.build_time[4][3] = 360;
    this.build_time[4][4] = 2700;
    this.build_time[4][5] = 6075;
    this.build_time[4][6] = 12150;
    this.build_time[4][7] = 22500;
    this.build_time[4][8] = 35820;
    this.build_time[4][9] = 53880;
    this.build_time[4][10] = 81720;

    this.build_time[20] = new Array(); //Warehouse
    this.build_time[20][1] = 15;
    this.build_time[20][2] = 36;
    this.build_time[20][3] = 240;
    this.build_time[20][4] = 1800;
    this.build_time[20][5] = 4050;
    this.build_time[20][6] = 4500;
    this.build_time[20][7] = 14760;
    this.build_time[20][8] = 23850;
    this.build_time[20][9] = 35910;
    this.build_time[20][10] = 54450;

    this.build_time[23] = new Array(); //City Wall
    this.build_time[23][1] = 30;
    this.build_time[23][2] = 1200;
    this.build_time[23][3] = 3600;
    this.build_time[23][4] = 10800;
    this.build_time[23][5] = 18000;
    this.build_time[23][6] = 28800;
    this.build_time[23][7] = 43200;
    this.build_time[23][8] = 64800;
    this.build_time[23][9] = 90000;
    this.build_time[23][10] = 126000;

    this.build_time[2] = new Array(); //Quarry
    this.build_time[2][1] = 15;
    this.build_time[2][2] = 54;
    this.build_time[2][3] = 360;
    this.build_time[2][4] = 2700;
    this.build_time[2][5] = 6075;
    this.build_time[2][6] = 12150;
    this.build_time[2][7] = 22500;
    this.build_time[2][8] = 35820;
    this.build_time[2][9] = 53880;
    this.build_time[2][10] = 81720;

    this.build_time[9] = new Array(); //Hideout
    this.build_time[9][1] = 15;
    this.build_time[9][2] = 36;
    this.build_time[9][3] = 240;
    this.build_time[9][4] = 1800;
    this.build_time[9][5] = 4050;
    this.build_time[9][6] = 8100;
    this.build_time[9][7] = 14760;
    this.build_time[9][8] = 23850;
    this.build_time[9][9] = 35910;
    this.build_time[9][10] = 54450;

    this.build_time[38] = new Array(); //Lookout Tower
    this.build_time[38][1] = 25;
    this.build_time[38][2] = 300;
    this.build_time[38][3] = 810;
    this.build_time[38][4] = 1500;
    this.build_time[38][5] = 2400;
    this.build_time[38][6] = 3600;
    this.build_time[38][7] = 4920;
    this.build_time[38][8] = 6600;
    this.build_time[38][9] = 8700;
    this.build_time[38][10] = 12000;

    this.build_time[3] = new Array(); //Farm
    this.build_time[3][1] = 15;
    this.build_time[3][2] = 54;
    this.build_time[3][3] = 360;
    this.build_time[3][4] = 2700;
    this.build_time[3][5] = 6075;
    this.build_time[3][6] = 12150;
    this.build_time[3][7] = 22500;
    this.build_time[3][8] = 35820;
    this.build_time[3][9] = 53880;
    this.build_time[3][10] = 81720;

    this.build_time[15] = new Array(); //City Guard House
    this.build_time[15][1] = 17;
    this.build_time[15][2] = 72;
    this.build_time[15][3] = 480;
    this.build_time[15][4] = 3600;
    this.build_time[15][5] = 8100;
    this.build_time[15][6] = 16200;
    this.build_time[15][7] = 29520;
    this.build_time[15][8] = 47700;
    this.build_time[15][9] = 71820;
    this.build_time[15][10] = 109200;

    this.build_time[41] = new Array(); //Ranger Tower
    this.build_time[41][1] = 25;
    this.build_time[41][2] = 300;
    this.build_time[41][3] = 810;
    this.build_time[41][4] = 1500;
    this.build_time[41][5] = 2400;
    this.build_time[41][6] = 3600;
    this.build_time[41][7] = 4920;
    this.build_time[41][8] = 6600;
    this.build_time[41][9] = 8700;
    this.build_time[41][10] = 12000;

    this.build_time[6] = new Array(); //Iron Mine
    this.build_time[6][1] = 15;
    this.build_time[6][2] = 54;
    this.build_time[6][3] = 360;
    this.build_time[6][4] = 2700;
    this.build_time[6][5] = 6075;
    this.build_time[6][6] = 12150;
    this.build_time[6][7] = 22500;
    this.build_time[6][8] = 35820;
    this.build_time[6][9] = 53880;
    this.build_time[6][10] = 81720;

    this.build_time[14] = new Array(); //Barracks
    this.build_time[14][1] = 15;
    this.build_time[14][2] = 36;
    this.build_time[14][3] = 240;
    this.build_time[14][4] = 1800;
    this.build_time[14][5] = 4050;
    this.build_time[14][6] = 8100;
    this.build_time[14][7] = 14760;
    this.build_time[14][8] = 23850;
    this.build_time[14][9] = 35910;
    this.build_time[14][10] = 54450;

    this.build_time[16] = new Array(); //Training Ground
    this.build_time[16][1] = 20;
    this.build_time[16][2] = 108;
    this.build_time[16][3] = 720;
    this.build_time[16][4] = 5400;
    this.build_time[16][5] = 12150;
    this.build_time[16][6] = 24300;
    this.build_time[16][7] = 44280;
    this.build_time[16][8] = 71550;
    this.build_time[16][9] = 107730;
    this.build_time[16][10] = 163350;

    this.build_time[13] = new Array(); //Townhouse
    this.build_time[13][1] = 17;
    this.build_time[13][2] = 77;
    this.build_time[13][3] = 480;
    this.build_time[13][4] = 3600;
    this.build_time[13][5] = 8100;
    this.build_time[13][6] = 16200;
    this.build_time[13][7] = 29520;
    this.build_time[13][8] = 47700;
    this.build_time[13][9] = 71820;
    this.build_time[13][10] = 108900;

    this.build_time[5] = new Array(); //Marketplace
    this.build_time[5][1] = 20;
    this.build_time[5][2] = 108;
    this.build_time[5][3] = 720;
    this.build_time[5][4] = 5400;
    this.build_time[5][5] = 12150;
    this.build_time[5][6] = 24300;
    this.build_time[5][7] = 44280;
    this.build_time[5][8] = 71550;
    this.build_time[5][9] = 107730;
    this.build_time[5][10] = 163350;

    this.build_time[43] = new Array(); //Pitfall Trap
    this.build_time[43][1] = 25;
    this.build_time[43][2] = 300;
    this.build_time[43][3] = 810;
    this.build_time[43][4] = 1500;
    this.build_time[43][5] = 2400;
    this.build_time[43][6] = 3600;
    this.build_time[43][7] = 4920;
    this.build_time[43][8] = 6600;
    this.build_time[43][9] = 8700;
    this.build_time[43][10] = 12000;

    this.build_time[7] = new Array(); //Sawmill
    this.build_time[7][1] = 20;
    this.build_time[7][2] = 108;
    this.build_time[7][3] = 720;
    this.build_time[7][4] = 5400;
    this.build_time[7][5] = 12150;
    this.build_time[7][6] = 24300;
    this.build_time[7][7] = 44280;
    this.build_time[7][8] = 71550;
    this.build_time[7][9] = 107730;
    this.build_time[7][10] = 163350;

    this.build_time[17] = new Array(); //Stable
    this.build_time[17][1] = 22;
    this.build_time[17][2] = 144;
    this.build_time[17][3] = 960;
    this.build_time[17][4] = 7200;
    this.build_time[17][5] = 16200;
    this.build_time[17][6] = 32400;
    this.build_time[17][7] = 59040;
    this.build_time[17][8] = 95400;
    this.build_time[17][9] = 143640;
    this.build_time[17][10] = 217800;

    this.build_time[40] = new Array(); //Guardian Tower
    this.build_time[40][1] = 25;
    this.build_time[40][2] = 300;
    this.build_time[40][3] = 810;
    this.build_time[40][4] = 1500;
    this.build_time[40][5] = 2400;
    this.build_time[40][6] = 3600;
    this.build_time[40][7] = 4920;
    this.build_time[40][8] = 6600;
    this.build_time[40][9] = 8700;
    this.build_time[40][10] = 12000;

    this.build_time[10] = new Array(); //Stonemason
    this.build_time[10][1] = 20;
    this.build_time[10][2] = 108;
    this.build_time[10][3] = 720;
    this.build_time[10][4] = 5400;
    this.build_time[10][5] = 12150;
    this.build_time[10][6] = 24300;
    this.build_time[10][7] = 44280;
    this.build_time[10][8] = 71550;
    this.build_time[10][9] = 107730;
    this.build_time[10][10] = 163350;

    this.build_time[36] = new Array(); //Moonglow Tower
    this.build_time[36][1] = 22;
    this.build_time[36][2] = 144;
    this.build_time[36][3] = 960;
    this.build_time[36][4] = 7200;
    this.build_time[36][5] = 16200;
    this.build_time[36][6] = 32400;
    this.build_time[36][7] = 59040;
    this.build_time[36][8] = 95400;
    this.build_time[36][9] = 143640;
    this.build_time[36][10] = 217800;

    this.build_time[44] = new Array(); //Barricade
    this.build_time[44][1] = 25;
    this.build_time[44][2] = 300;
    this.build_time[44][3] = 810;
    this.build_time[44][4] = 1500;
    this.build_time[44][5] = 2400;
    this.build_time[44][6] = 3600;
    this.build_time[44][7] = 4920;
    this.build_time[44][8] = 6600;
    this.build_time[44][9] = 8700;
    this.build_time[44][10] = 12000;

    this.build_time[8] = new Array(); //Mill
    this.build_time[8][1] = 20;
    this.build_time[8][2] = 108;
    this.build_time[8][3] = 720;
    this.build_time[8][4] = 5400;
    this.build_time[8][5] = 12150;
    this.build_time[8][6] = 24300;
    this.build_time[8][7] = 44280;
    this.build_time[8][8] = 71550;
    this.build_time[8][9] = 107730;
    this.build_time[8][10] = 163350;

    this.build_time[21] = new Array(); //Castle
    this.build_time[21][1] = 72000;
    this.build_time[21][2] = 84000;
    this.build_time[21][3] = 96000;
    this.build_time[21][4] = 108000;
    this.build_time[21][5] = 120000;
    this.build_time[21][6] = 132000;
    this.build_time[21][7] = 144000;
    this.build_time[21][8] = 156000;
    this.build_time[21][9] = 168000;
    this.build_time[21][10] = 180000;

    this.build_time[37] = new Array(); //Trinsic Temple
    this.build_time[37][1] = 22;
    this.build_time[37][2] = 144;
    this.build_time[37][3] = 960;
    this.build_time[37][4] = 7200;
    this.build_time[37][5] = 16200;
    this.build_time[37][6] = 32400;
    this.build_time[37][7] = 59040;
    this.build_time[37][8] = 95400;
    this.build_time[37][9] = 143640;
    this.build_time[37][10] = 217800;

    this.build_time[42] = new Array(); //Templar Tower
    this.build_time[42][1] = 25;
    this.build_time[42][2] = 300;
    this.build_time[42][3] = 810;
    this.build_time[42][4] = 1500;
    this.build_time[42][5] = 2400;
    this.build_time[42][6] = 3600;
    this.build_time[42][7] = 4920;
    this.build_time[42][8] = 6600;
    this.build_time[42][9] = 8700;
    this.build_time[42][10] = 12000;

    this.build_time[45] = new Array(); //Arcane Trap
    this.build_time[45][1] = 25;
    this.build_time[45][2] = 300;
    this.build_time[45][3] = 810;
    this.build_time[45][4] = 1500;
    this.build_time[45][5] = 2400;
    this.build_time[45][6] = 3600;
    this.build_time[45][7] = 4920;
    this.build_time[45][8] = 6600;
    this.build_time[45][9] = 8700;
    this.build_time[45][10] = 12000;

    this.build_time[11] = new Array(); //Foundry
    this.build_time[11][1] = 20;
    this.build_time[11][2] = 108;
    this.build_time[11][3] = 720;
    this.build_time[11][4] = 5400;
    this.build_time[11][5] = 12150;
    this.build_time[11][6] = 24300;
    this.build_time[11][7] = 44280;
    this.build_time[11][8] = 71550;
    this.build_time[11][9] = 107730;
    this.build_time[11][10] = 163350;

    this.build_time[39] = new Array(); //Ballista Tower
    this.build_time[39][1] = 25;
    this.build_time[39][2] = 300;
    this.build_time[39][3] = 810;
    this.build_time[39][4] = 1500;
    this.build_time[39][5] = 2400;
    this.build_time[39][6] = 3600;
    this.build_time[39][7] = 4920;
    this.build_time[39][8] = 6600;
    this.build_time[39][9] = 8700;
    this.build_time[39][10] = 12000;

    this.build_time[18] = new Array(); //Workshop
    this.build_time[18][1] = 25;
    this.build_time[18][2] = 180;
    this.build_time[18][3] = 1200;
    this.build_time[18][4] = 9000;
    this.build_time[18][5] = 20250;
    this.build_time[18][6] = 40500;
    this.build_time[18][7] = 73800;
    this.build_time[18][8] = 119250;
    this.build_time[18][9] = 179550;
    this.build_time[18][10] = 272250;

    this.build_time[22] = new Array(); //Harbor
    this.build_time[22][1] = 22;
    this.build_time[22][2] = 144;
    this.build_time[22][3] = 960;
    this.build_time[22][4] = 7200;
    this.build_time[22][5] = 16200;
    this.build_time[22][6] = 32400;
    this.build_time[22][7] = 59040;
    this.build_time[22][8] = 95400;
    this.build_time[22][9] = 143640;
    this.build_time[22][10] = 217800;

    this.build_time[19] = new Array(); //Shipyard
    this.build_time[19][1] = 27;
    this.build_time[19][2] = 216;
    this.build_time[19][3] = 1440;
    this.build_time[19][4] = 10800;
    this.build_time[19][5] = 24300;
    this.build_time[19][6] = 48600;
    this.build_time[19][7] = 88560;
    this.build_time[19][8] = 143100;
    this.build_time[19][9] = 215460;
    this.build_time[19][10] = 326700;

    this.build_time[46] = new Array(); //Camouflage Trap
    this.build_time[46][1] = 25;
    this.build_time[46][2] = 300;
    this.build_time[46][3] = 810;
    this.build_time[46][4] = 1500;
    this.build_time[46][5] = 2400;
    this.build_time[46][6] = 3600;
    this.build_time[46][7] = 4920;
    this.build_time[46][8] = 6600;
    this.build_time[46][9] = 8700;
    this.build_time[46][10] = 12000;

}

// ---------------------

LouProof.prototype.get_lowest_level_building = function( btype) {
    var buildings = a.visMain.getBuildings();
    
    var lowest_level = 10;
    var lowest_bld;
    var lowest_time = 10000000;
    var s='';
    
    for (var i in buildings) {
        
        if( isNaN(i)) continue;
        
        bld = buildings[i];

        var el = bld.getLevel() + this.qcount( bld); // effective level (level + queue entry count)
        
        if( (el < lowest_level && localStorage["lowest_build_time"] != "true") ||
            ( localStorage["lowest_build_time"] == "true"
                && this.build_time[ bld.getType()][ el+1] < lowest_time)
        ) {

            if( this.is_resource( bld.getType())) continue;
            if( btype == 'common'   && !this.is_common_btype( bld.getType())) continue;
            if( btype == 'tower'    && !this.is_tower( bld.getType())) continue;
            if( btype == 'barracks' && !this.is_barracks( bld.getType())) continue;
            if( btype == 'cottage'  && !this.is_cottage( bld.getType())) continue;
            if( btype == 'military' && !this.is_military( bld.getType())) continue;

            if( debuck && lowest_bld) { // -- Debug information
                this.log( "switching level "+lowest_level+" "+this.getBldTypeName( lowest_bld.getType())+" ("+lowest_time+")"
                +" with level "+bld.getLevel()+" "+ this.getBldTypeName( bld.getType())+" ("+this.build_time[ bld.getType()][ el+1]+")"
                );
                this.log( (el < lowest_level && localStorage["lowest_build_time"] != "true"));
                this.log( ( localStorage["lowest_build_time"] == "true" && this.build_time[ bld.getType()][ el+1] < lowest_time));
            }
            // -- debug

            if( debuck) this.log( 'get_llb: bld.getLevel() = '+bld.getLevel()+
                ', qcount( bld) = '+this.qcount(bld)+
                ', el = '+el+
                ', lowest_level = '+lowest_level);
            lowest_bld = bld;
            lowest_level = el;
            lowest_time = this.build_time[ bld.getType()][ el+1];
        }
    }
    
    if( debuck) this.log( bld);

    return( lowest_bld);
}

louproof = new LouProof();
setTimeout( "louproof.init();", 5000);
